

class AsyncLinkNode{
    next:AsyncLinkNode|null = null;
    prev:AsyncLinkNode|null = null;
    execFn:()=>void;
    execNext(){
        if(this.next){
            this.next.execFn();
        }
    }
    constructor(execFn:(...args: any)=>void){
        this.execFn = function(...args){
            execFn(this.execNext,...args);
        }
    }

}

export default  class AsyncLink{
    header:AsyncLinkNode|null = null;
    tail:AsyncLinkNode|null = null;
    size:number = 0;
    push(execFn:(...args: any)=>void){
        if(this.header==null){
            this.header = new AsyncLinkNode(execFn);
        }else if(this.header && this.tail==null){
            this.tail = new AsyncLinkNode(execFn);
            this.header.next = this.tail;
            this.tail.prev = this.header;
        }else if(this.tail){
            const currentTtail = this.tail;
            const newNode = new AsyncLinkNode(execFn);
            this.tail = this.tail.next = newNode
            newNode.prev = currentTtail;
        }
    }

}